/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
// rights reserved.

#include "quakedef.h"

#define QMCISONGDEVICE "weenixloonies"

#define MUSICFORMAT_NONE	0
#define MUSICFORMAT_MCI		1
#define MUSICFORMAT_OGG		2

int MusicFormat = MUSICFORMAT_NONE;

static void CDAudio_Eject (void)
{
}


static void CDAudio_CloseDoor (void)
{
}


static int CDAudio_GetAudioDiskInfo (void)
{
	return -1;
}


BOOL FindMediaFile (char *path, byte track, BOOL looping)
{
	char *tracks[100];
	int numtracks = 0;
	char *good_codecs[] = {"mp3", "wma", "wav", NULL};
	searchpath_t *search;
	int i, j;

	for (i = 0; ; i++)
	{
		if (!good_codecs[i]) break;

		for (search = com_searchpaths; search; search = search->next)
		{
			WIN32_FIND_DATA FindFileData;
			HANDLE hFind = INVALID_HANDLE_VALUE;
			char find_filter[MAX_PATH];
			int mark;

			if (search->pack) continue;

			sprintf (find_filter, "%s/%s*.%s", search->filename, path, good_codecs[i]);
			numtracks = 0;

			for (j = 0; j < 100; j++)
				tracks[j] = NULL;

			for (j = 0; ; j++)
			{
				if (find_filter[j] == 0) break;
				if (find_filter[j] == '/') find_filter[j] = '\\';
			}

			hFind = FindFirstFile (find_filter, &FindFileData);

			if (hFind == INVALID_HANDLE_VALUE)
			{
				// found no files
				FindClose (hFind);
				continue;
			}

			mark = qScratch->GetLowMark ();

			do
			{
				// not interested
				int badattrib = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_OFFLINE;

				if (FindFileData.dwFileAttributes & badattrib) continue;
				if (numtracks > 99) continue;

				tracks[numtracks] = (char *) qScratch->FastAlloc (strlen (FindFileData.cFileName) + 1);
				strcpy (tracks[numtracks], FindFileData.cFileName);
				numtracks++;
			} while (FindNextFile (hFind, &FindFileData));

			FindClose (hFind);

			// (track numbers begin at 2 in Quake)
			if (numtracks && track > 1 && track < (numtracks + 2))
			{
				// compose the string to send
				char *mciString = va ("open \"%s/%s%s\" type mpegvideo alias "QMCISONGDEVICE, search->filename, path, tracks[track - 2]);

				// 0 if successful - needs filename in quotes as it may contain spaces (track numbers begin at 2 in Quake)
				if (!mciSendString (mciString, NULL, 0, 0))
				{
					// do an initial volume set
					int s_volume = (int) (bgmvolume->value * 1000.0f);

					if (s_volume < 0) s_volume = 0;
					if (s_volume > 1000) s_volume = 1000;

					if (!mciSendString (va ("setaudio "QMCISONGDEVICE" volume to %i", s_volume), NULL, 0, 0))
					{
						// and attempt to play it
						if (!mciSendString ("set "QMCISONGDEVICE" video off", NULL, 0, 0))	// in case the file contains video info
						{
							if (!mciSendString (va ("play "QMCISONGDEVICE"%s", looping ? " repeat" : ""), NULL, 0, 0))
							{
								// got it
								qScratch->FreeToLowMark (mark);
								MusicFormat = MUSICFORMAT_MCI;
								return TRUE;
							}
						}
					}
				}
			}

			// failed; close in case we had opened it, then free memory and get out
			mciSendString ("close "QMCISONGDEVICE, NULL, 0, 0);
			qScratch->FreeToLowMark (mark);
		}
	}

	return FALSE;
}


void CDAudio_Play (byte track, BOOL looping)
{
	int mark = qScratch->GetLowMark ();

	// stop any previous tracks
	CDAudio_Stop ();

	// every other ID game that uses music tracks in the filesystem has them in music, so it's
	// a reasonable assumption that that's what users will be expecting...
	if (!FindMediaFile ("music/", track, looping))
	{
		// darkplaces on the other hand does something *completely* different.  standards?  who needs 'em!
		FindMediaFile ("sound/cdtracks/", track, looping);
	}

	qScratch->FreeToLowMark (mark);
}


void CDAudio_Stop (void)
{
	if (MusicFormat == MUSICFORMAT_MCI)
	{
		mciSendString ("stop "QMCISONGDEVICE, NULL, 0, 0);
		mciSendString ("close "QMCISONGDEVICE, NULL, 0, 0);
	}

	MusicFormat = MUSICFORMAT_NONE;
}


void CDAudio_Pause (void)
{
	if (MusicFormat == MUSICFORMAT_MCI)
		mciSendString ("pause "QMCISONGDEVICE, NULL, 0, 0);
}


void CDAudio_Resume (void)
{
	if (MusicFormat == MUSICFORMAT_MCI)
		mciSendString ("resume "QMCISONGDEVICE, NULL, 0, 0);
}


static void CD_f (void)
{
	/*
	on
	off
	reset
	remap
	close
	play
	loop
	stop
	pause
	resume
	eject
	info
	*/
}


void CDAudio_Update (void)
{
	if (MusicFormat == MUSICFORMAT_MCI)
	{
		static int lastvolume = -1;
		int s_volume = (int) (bgmvolume->value * 1000.0f);

		if (s_volume < 0) s_volume = 0;
		if (s_volume > 1000) s_volume = 1000;

		if (lastvolume != s_volume)
		{
			// yayy - linear scale!
			mciSendString (va ("setaudio "QMCISONGDEVICE" volume to %i", s_volume), NULL, 0, 0);
			lastvolume = s_volume;
		}
	}
}


void CDAudio_Init (void)
{
	MusicFormat = MUSICFORMAT_NONE;
}


void CDAudio_Shutdown (void)
{
	// stop everything
	CDAudio_Stop ();
}

